/* Basirudin Rachman - 2011
 * b@rachmans.com
 */

using System;
using System.Collections.Generic;
using System.ServiceModel.DomainServices.Client;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Navigation;
using Imtihan.Web;

namespace Imtihan
{
    public partial class Admin : Page
    {
        ImtihanDomainContext _context = new ImtihanDomainContext();
        List<ProblemType> _problemTypes = new List<ProblemType>();

        public Admin()
        {
            InitializeComponent();
        }

        private void loadProblem()
        {
            //  Load Answer.
            _context.Load(_context.GetProblemsQuery(), (op) =>
            {
                dgProblem.ItemsSource = op.Entities;
            }, null);
        }

        Control _ctlQuestion = null;
        private void loadQuestion(Control ctlQuestion)
        {
            _ctlQuestion = ctlQuestion;

            //  Load Question.
            _context.Load(_context.GetQuestionsQuery().OrderBy(q => q.Sentence), (opQuestion) =>
            {
                opQuestion.Completed += new EventHandler(opQuestion_Completed);
            }, null);
        }

        void opQuestion_Completed(object sender, EventArgs e)
        {
            if (_ctlQuestion is DataGrid)
            {
                (_ctlQuestion as DataGrid).ItemsSource = (sender as LoadOperation<Question>).Entities;
            }
            else if (_ctlQuestion is ListBox)
            {
                (_ctlQuestion as ListBox).ItemsSource = (sender as LoadOperation<Question>).Entities;
            }
            else if (_ctlQuestion is ComboBox)
            {
                (_ctlQuestion as ComboBox).ItemsSource = (sender as LoadOperation<Question>).Entities;
            }
        }

        Control _ctlAnswer = null;
        private void loadAnswer(Control ctlAnswer)
        {
            _ctlAnswer = ctlAnswer;

            //  Load Question.
            _context.Load(_context.GetAnswersQuery().OrderBy(a => a.Words), (opAnswer) =>
            {
                //dgQuestion.ItemsSource = op.Entities;
                opAnswer.Completed += new EventHandler(opAnswer_Completed);
            }, null);
        }

        void opAnswer_Completed(object sender, EventArgs e)
        {
            if (_ctlAnswer is DataGrid)
            {
                (_ctlAnswer as DataGrid).ItemsSource = (sender as LoadOperation<Answer>).Entities;
            }
            else if (_ctlAnswer is ListBox)
            {
                (_ctlAnswer as ListBox).ItemsSource = (sender as LoadOperation<Answer>).Entities;
            }
            else if (_ctlAnswer is ComboBox)
            {
                (_ctlAnswer as ComboBox).ItemsSource = (sender as LoadOperation<Answer>).Entities;
            }
        }

        private void loadCategory(Control ctlCategory)
        {
            _ctlCategory = ctlCategory;

            //  Load Category.
            _context.Load(_context.GetCategoriesQuery(), (op) =>
            {
                op.Completed += new EventHandler(op_Completed);
            }, null);
        }

        Control _ctlCategory = null;
        void op_Completed(object sender, EventArgs e)
        {
            //throw new NotImplementedException();
            if (_ctlCategory is DataGrid)
            {
                (_ctlCategory as DataGrid).ItemsSource = (sender as LoadOperation<Category>).Entities;
            }
            else if (_ctlCategory is ListBox)
            {
                (_ctlCategory as ListBox).ItemsSource = (sender as LoadOperation<Category>).Entities;
            }
            else if (_ctlCategory is ComboBox)
            {
                (_ctlCategory as ComboBox).ItemsSource = (sender as LoadOperation<Category>).Entities;
            }
        }

        // Executes when the user navigates to this page.
        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            _problemTypes.Add(new ProblemType { Code = "M", Type = "Multiple Choice" });
            _problemTypes.Add(new ProblemType { Code = "E", Type = "Essay/Written" });
            cbProblemType.ItemsSource = _problemTypes;

            loadAnswer(dgAnswer);
            loadQuestion(dgQuestion);
            loadCategory(dgCategory);
            loadProblem();
            loadCategory(cbProblemCategory);

            dgAssessment.ItemsSource = _context.Assessments;
            _context.Load(_context.GetAssessmentsQuery());
        }

        private Answer _answer;
        private Question _question;
        private Category _category;

        private void btnEdit_Click(object sender, RoutedEventArgs e)
        {
            _mode = "Save";
            switch ((tabAdmin.SelectedItem as TabItem).Header.ToString())
            {
                case "Answer":
                    _answer = dgAnswer.SelectedItem as Answer;
                    cleanEditor();
                    rteAnswerWords.InsertString(_answer.Words);
                    btnAdd.Content = _mode;
                    break;
                case "Question":
                    _question = dgQuestion.SelectedItem as Question;
                    cleanEditor();
                    rteQuestionSentence.InsertString(_question.Sentence);
                    btnAddQuestion.Content = _mode;
                    break;
                case "Category":
                    _category = dgCategory.SelectedItem as Category;
                    cleanEditor();
                    tbCategory.Text = _category.Name;
                    btnAddCategory.Content = _mode;
                    break;
            }
        }

        private void btnDelete_Click(object sender, RoutedEventArgs e)
        {
            switch (_tabHeader)
            {
                case "Answer":
                    _context.Answers.Remove(dgAnswer.SelectedItem as Answer);

                    _context.SubmitChanges((op) =>
                    {
                        if (!op.HasError)
                        {
                            MessageBox.Show("Answer is successfully removed");
                            loadAnswer(dgAnswer);
                        }
                    }, null);
                    break;
                case "Question":
                    _context.Questions.Remove(dgQuestion.SelectedItem as Question);

                    _context.SubmitChanges((op) =>
                    {
                        if (!op.HasError)
                        {
                            MessageBox.Show("Question is successfully removed");
                            loadQuestion(dgQuestion);
                        }
                    }, null);
                    break;
                case "Category":
                    _context.Categories.Remove(dgCategory.SelectedItem as Category);

                    _context.SubmitChanges((op) =>
                    {
                        if (!op.HasError)
                        {
                            MessageBox.Show("Category is successfully removed");
                            loadCategory(dgCategory);
                        }
                    }, null);
                    break;
                case "Problem":
                    _context.Problems.Remove(dgProblem.SelectedItem as Problem);

                    _context.SubmitChanges((op) =>
                    {
                        if (!op.HasError)
                        {
                            MessageBox.Show("Problem is successfully removed");
                            loadProblem();
                        }
                    }, null);
                    break;
            }
        }

        private void btnAdd_Click(object sender, RoutedEventArgs e)
        {
            switch (_mode)
            {
                case "Add":
                    switch (_tabHeader)
                    {
                        case "Answer":
                            _context.Answers.Add(new Answer { Id = Guid.NewGuid(), Words = rteAnswerWords.QueryText().Text });

                            _context.SubmitChanges((op) =>
                            {
                                if (!op.HasError)
                                {
                                    MessageBox.Show("Answer is successfully added");
                                    loadAnswer(dgAnswer);
                                }
                            }, null);
                            break;
                        case "Question":
                            _context.Questions.Add(new Question { Id = Guid.NewGuid(), Sentence = rteQuestionSentence.QueryText().Text });

                            _context.SubmitChanges((op) =>
                            {
                                if (!op.HasError)
                                {
                                    MessageBox.Show("Question is successfully added");
                                    loadQuestion(dgQuestion);
                                }
                            }, null);
                            break;
                        case "Category":
                            _context.Categories.Add(new Category { Id = Guid.NewGuid(), Name = tbCategory.Text });

                            _context.SubmitChanges((op) =>
                            {
                                if (!op.HasError)
                                {
                                    MessageBox.Show("Category is successfully added");
                                    loadCategory(dgCategory);
                                }
                            }, null);
                            break;
                        case "Problem":
                            //_context.Problems.Add(new Problem { Id = Guid.NewGuid()  , Name = tbCategory.Text });
                            _context.Problems.Add(new Problem
                            {
                                Id = Guid.NewGuid(),
                                CategoryId = Guid.Parse(cbCategory.SelectedValue.ToString())
                                ,
                                QuestionId = Guid.Parse(cbQuestion.SelectedValue.ToString()),
                                Type = cbProblemType.SelectedValue.ToString()
                            });

                            _context.SubmitChanges((op) =>
                            {
                                if (!op.HasError)
                                {
                                    MessageBox.Show("Problem is successfully added");
                                    loadProblem();
                                }
                            }, null);
                            break;
                        case "Problem's Answer":
                            //_context.Problems.Add(new Problem { Id = Guid.NewGuid()  , Name = tbCategory.Text });
                            _selectedProblem.ProblemAnswers.Add(new ProblemAnswer { Id = Guid.NewGuid(), AnswerId = Guid.Parse(cbAnswer.SelectedValue.ToString())
                                , ProblemId = _selectedProblem.Id
                                , IsAnswer = chkIsAnswer.IsChecked });
                            _context.SubmitChanges((op) =>
                            {
                                if (!op.HasError)
                                {
                                    MessageBox.Show("Problem's Answer is successfully added");
                                    refreshProblemAnswer();
                                }
                            }, null);
                            break;
                    }
                    break;
                case "Save":
                    _mode = "Add";
                    switch (_tabHeader)
                    {
                        case "Answer":
                            _answer.Words = rteAnswerWords.QueryText().Text;
                            _context.SubmitChanges((op) =>
                            {
                                if (!op.HasError)
                                {
                                    MessageBox.Show("Answer is successfully updated");
                                    loadAnswer(dgAnswer);
                                    btnAdd.Content = _mode;
                                }
                            }, null);
                            break;
                        case "Question":
                            _question.Sentence = rteQuestionSentence.QueryText().Text;
                            _context.SubmitChanges((op) =>
                            {
                                if (!op.HasError)
                                {
                                    MessageBox.Show("Question is successfully updated");
                                    loadQuestion(dgQuestion);
                                    btnAddQuestion.Content = _mode;
                                }
                            }, null);
                            break;
                        case "Category":
                            _category.Name = tbCategory.Text;
                            _context.SubmitChanges((op) =>
                            {
                                if (!op.HasError)
                                {
                                    MessageBox.Show("Category is successfully updated");
                                    loadCategory(dgCategory);
                                    btnAddCategory.Content = _mode;
                                }
                            }, null);
                            break;
                    }
                    break;
            }
        }

        private void cleanEditor()
        {
            switch ((tabAdmin.SelectedItem as TabItem).Header.ToString())
            {
                case "Answer":
                    rteAnswerWords.SelectAll();
                    rteAnswerWords.RemoveSelection();
                    break;
                case "Question":
                    rteQuestionSentence.SelectAll();
                    rteQuestionSentence.RemoveSelection();
                    break;
                case "Category":
                    tbCategory.Text = string.Empty;
                    break;
            }
        }

        string _mode = "Add";

        private void btnCancel_Click(object sender, RoutedEventArgs e)
        {
            cleanEditor();

            _mode = "Add";
            switch (_tabHeader)
            {
                case "Answer":
                    btnAdd.Content = _mode;
                    break;
                case "Question":
                    btnAddQuestion.Content = _mode;
                    break;
                case "Category":
                    btnAddCategory.Content = _mode;
                    break;
            }
        }

        string _tabHeader = "Answer";

        private void tabAdmin_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            _tabHeader = (e.AddedItems[0] as TabItem).Header.ToString();

            if (_tabHeader == "Problem")
            {
                loadQuestion(cbQuestion);
                loadCategory(cbCategory);
            }
            else if (_tabHeader == "Problem's Answer")
            {
                loadAnswer(cbAnswer);
            }
        }

        private void cbProblemCategory_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
                _context.Load(_context.GetProblemsQuery().Where(p => p.CategoryId == (e.AddedItems[0] as Category).Id).OrderBy(pq => pq.Question.Sentence), (op) =>
            {
                cbProblemQuestion.ItemsSource = op.Entities;
            }, null);
        }

        private void cbProblemQuestion_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (e.AddedItems.Count > 0)
            {
                _context.Load(_context.GetProblemsQuery().Where(p => p.CategoryId == Guid.Parse(cbProblemCategory.SelectedValue.ToString())
                    && p.QuestionId == (e.AddedItems[0] as Problem).QuestionId), (op) =>
                {
                    cbProblemAnswerType.ItemsSource = op.Entities;
                }, null);
            }
        }

        Problem _selectedProblem = null;
        private void cbProblemAnswerType_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (cbProblemAnswerType.SelectedValue != null)
            {
                _context.Load(_context.GetProblemsQuery().Where(p => p.CategoryId == Guid.Parse(cbProblemCategory.SelectedValue.ToString())
                                && p.QuestionId == Guid.Parse(cbProblemQuestion.SelectedValue.ToString()) 
                                && p.Type.ToLower() == cbProblemAnswerType.SelectedValue.ToString().ToLower())
                                , (op) =>
                                {
                                    //Problem selectedProblem = null;
                                    foreach (Problem p in op.Entities)
                                    {
                                        _selectedProblem = p;
                                        break;
                                    }

                                    _context.Load(_context.GetProblemAnswersQuery().Where(pa => pa.ProblemId == _selectedProblem.Id), (opPa) =>
                                    {
                                        dgProblemAnswer.ItemsSource = opPa.Entities;
                                    }
                                    , null);
                                }, null);
            }
        }

        private void refreshProblemAnswer()
        {
            _context.Load(_context.GetProblemAnswersQuery().Where(pa => pa.ProblemId == _selectedProblem.Id), (opPa) =>
            {
                dgProblemAnswer.ItemsSource = opPa.Entities;
            }
                    , null);
        }
    }

    public class ProblemType
    {
        public string Code { get; set; }
        public string Type { get; set; }
    }


}
